package com.sgl.gk.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.sg.comm.common.Ret;
import com.sg.comm.opcuav2.NodeDTOV2;
import com.sg.comm.opcuav2.OpcUaReadReqV2;
import com.sg.comm.opcuav2.OpcUaWriteReqV2;
import com.sg.comm.opcuav2.batch.BatchReadDTO;
import com.sg.comm.service.OpcUaServiceV2;
import com.sgl.common.core.domain.AjaxResult;
import com.sgl.common.utils.StringUtils;
import com.sgl.gk.controller.vo.GkProductionLineVo;
import com.sgl.gk.controller.vo.GkStationConfigurationVo;
import com.sgl.gk.controller.vo.GkStationVo;
import com.sgl.gk.dict.StationDict;
import com.sgl.gk.domain.*;
import com.sgl.gk.domain.plc.Node;
import com.sgl.gk.domain.plc.OpcUa;
import com.sgl.gk.domain.plc.OpcUaList;
import com.sgl.gk.mapper.*;
import com.sgl.gk.scheduled.ScheduledTask;
import com.sgl.gk.scheduled.vo.ServiceData;
import com.sgl.gk.scheduled.vo.SocketDataVo;
import com.sgl.gk.service.GkSettingLogService;
import com.sgl.gk.service.GkStationConfigurationService;
import com.sgl.gk.service.GkStationConfigureTemplateService;
import com.sgl.gk.service.GkStationService;
import com.sgl.gk.tools.OpcUATool;
import com.sgl.gk.tools.ReadOpcUaNodeInfoTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class GkStationServiceImpl implements GkStationService {

    @Autowired
    GkStationMapper gkStationMapper;

    @Autowired
    GkStationTypeConfigurationMapper gkStationTypeConfigurationMapper;

    @Autowired
    GkStationConfigurationMapper gkStationConfigurationMapper;

    @Autowired
    GkStationConfigurationValuesMapper gkStationConfigurationValuesMapper;

    @Autowired
    GkStationEventMapper gkStationEventMapper;

    @Autowired
    GkProductMapper gkProductMapper;

    @Autowired
    GkProductionLineMapper gkProductionLineMapper;

    @Autowired
    GkSignalCommunicationMapper gkSignalCommunicationMapper;

    @Autowired
    GkStationTypeEventMapper gkStationTypeEventMapper;

    @Autowired
    GkStationConfigureTemplateMapper gkStationConfigureTemplateMapper;

    @Autowired
    GkStationConfigureTemplateService gkStationConfigureTemplateService;

    @Autowired
    GkSettingLogService gkSettingLogService;

    @Autowired
    GkReservedInfoMapper gkReservedInfoMapper;

    @DubboReference(version = "1.0.0", url = "dubbo://127.0.0.1:20880", check = false,timeout = 15000)
    private OpcUaServiceV2 opcUaServiceV2;

    @Value("${communication.mode}")
    public String communication;

    @Override
    public List<GkStationVo> list(GkStation gkStation) {
        gkStation.setName(StringUtils.trim(gkStation.getName()));
        List<GkStationVo> list = gkStationMapper.list(gkStation);
        if (list!=null&&list.size()>0) {
            List<Long> productIds = list.stream().map(gkStationVo -> gkStationVo.getProductId()).distinct().collect(Collectors.toList());
            List<Long> productionLineIds = list.stream().map(gkStationVo -> gkStationVo.getProductionLineId()).distinct().collect(Collectors.toList());
            List<Long> signalCommunicationIds = list.stream().map(gkStationVo -> gkStationVo.getSignalCommunicationId()).distinct().collect(Collectors.toList());

            List<GkProduct> gkProductList = gkProductMapper.selectByIds(productIds);
            List<GkProductionLineVo> gkProductionLineVos = gkProductionLineMapper.selectInfoByIds(productionLineIds);
            List<GkSignalCommunication> gkSignalCommunicationList = gkSignalCommunicationMapper.selectInfoByIds(signalCommunicationIds);

            int type2Num = 0;
            for (GkStationVo gkStationVo : list) {
                Long productionLineId = gkStationVo.getProductionLineId();
                Long productId = gkStationVo.getProductId();
                Long signalCommunicationId = gkStationVo.getSignalCommunicationId();
                for (GkProduct gkProduct : gkProductList) {
                    if (gkProduct.getId().equals(productId)) {
                        gkStationVo.setProductName(gkProduct.getName());
                    }
                }
                if (gkStationVo.getConfigureType() == 2) {
                    type2Num += 1;
                }
                for (GkProductionLineVo gkProductionLineVo : gkProductionLineVos) {
                    if (productionLineId.equals(gkProductionLineVo.getId())) {
                        gkStationVo.setProductionLineName(gkProductionLineVo.getName());
                    }
                }
                for (GkSignalCommunication gkSignalCommunication : gkSignalCommunicationList) {
                    if (gkSignalCommunication.getId().equals(signalCommunicationId)) {
                        gkStationVo.setPlcType(gkSignalCommunication.getType());
                        gkStationVo.setSignalName(gkSignalCommunication.getName());
                    }
                }
            }
        }
        List<GkStationVo> collect = list.stream().sorted(Comparator.comparing(GkStationVo::getDefaultStation).reversed()).collect(Collectors.toList());
        return collect;
    }

    @Transactional
    @Override
    public AjaxResult add(GkStation gkStation) {
        if (gkStation.getStationTypeId() == null||StringUtils.isEmpty(gkStation.getName())) {
            return AjaxResult.error("必填字段验证不通过");
        }
        gkStation.setCreateAt(new Date());
        gkStation.setLastModifyAt(new Date());
        gkStation.setConfigureType(1);

        int row = gkStationMapper.add(gkStation);
        if (row>0){
            // 得到工位类型中的配置变量
            GkStationTypeConfiguration gkStationTypeConfiguration = new GkStationTypeConfiguration();
            gkStationTypeConfiguration.setStationTypeId(gkStation.getStationTypeId());
            List<GkStationTypeConfiguration> list = gkStationTypeConfigurationMapper.list(gkStationTypeConfiguration);

            Long stationId = gkStationMapper.selectId();
            if (list.size()>0) {
                List<GkStationConfiguration> gkStationConfigurationList = new ArrayList<>();
                for (GkStationTypeConfiguration stationTypeConfiguration : list) {
                    if (stationTypeConfiguration.getType()!=3&&stationTypeConfiguration.getType()!=4) {
                        Date date = new Date();
                        GkStationConfiguration gkStationConfiguration = new GkStationConfiguration();
                        gkStationConfiguration.setStationId(stationId);
                        gkStationConfiguration.setType(stationTypeConfiguration.getType());
                        // namespace 在工位类型中没有所有不传
                        gkStationConfiguration.setVariableName(StringUtils.trim(stationTypeConfiguration.getVariableName()));
                        gkStationConfiguration.setDisplayName(StringUtils.trim(stationTypeConfiguration.getDisplayName()));
                        gkStationConfiguration.setDataType(StringUtils.trim(stationTypeConfiguration.getDataType()));
                        gkStationConfiguration.setVariableComments(StringUtils.trim(stationTypeConfiguration.getVariableComments()));
                        gkStationConfiguration.setVariableRemarks(StringUtils.trim(stationTypeConfiguration.getVariableRemarks()));
                        gkStationConfiguration.setDefaultValue(StringUtils.trim(stationTypeConfiguration.getDefaultValue()));
                        gkStationConfiguration.setVariableIndex(stationTypeConfiguration.getVariableIndex());
                        gkStationConfiguration.setResultConversion(stationTypeConfiguration.getResultConversion());
                        gkStationConfiguration.setCheckLength(stationTypeConfiguration.getCheckLength() == null ? 0 : stationTypeConfiguration.getCheckLength());
                        gkStationConfiguration.setZeroValue(stationTypeConfiguration.getZeroValue()==null?"":stationTypeConfiguration.getZeroValue());
                        gkStationConfiguration.setOneValue(stationTypeConfiguration.getOneValue()==null?"":stationTypeConfiguration.getOneValue());
                        gkStationConfiguration.setThreeValue(stationTypeConfiguration.getThreeValue()==null?"":stationTypeConfiguration.getThreeValue());
                        gkStationConfiguration.setFourValue(stationTypeConfiguration.getFourValue()==null?"":stationTypeConfiguration.getFourValue());
                        gkStationConfiguration.setTwoValue(stationTypeConfiguration.getTwoValue()==null?"":stationTypeConfiguration.getTwoValue());
                        gkStationConfiguration.setFiveValue(stationTypeConfiguration.getFiveValue()==null?"":stationTypeConfiguration.getFiveValue());
                        gkStationConfiguration.setCreateAt(date);
                        gkStationConfiguration.setLastModifyAt(date);
                        gkStationConfiguration.setToUse(1);
                        gkStationConfigurationList.add(gkStationConfiguration);
                    }
                }
                row = gkStationConfigurationMapper.saveList(gkStationConfigurationList);
            }
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @Transactional
    @Override
    public AjaxResult edit(GkStation gkStation) {
        if (gkStation.getDefaultStation()!=1) {
            if (gkStation.getStationTypeId() == null || StringUtils.isEmpty(gkStation.getName())) {
                return AjaxResult.error("必填字段验证不通过");
            }
        }
        List<GkStation> gkStations = gkStationMapper.selectByProductionIds(Collections.singletonList(gkStation.getProductionLineId()));
        int row = gkStationMapper.edit(gkStation);
        if (row>0){
            if (gkStation.getDefaultStation()==0) {
                GkStationTypeConfiguration gkStationTypeConfiguration = new GkStationTypeConfiguration();
                gkStationTypeConfiguration.setStationTypeId(gkStation.getStationTypeId());
                // 工位类型变量信息
                List<GkStationTypeConfiguration> list = gkStationTypeConfigurationMapper.list(gkStationTypeConfiguration);

                Long[] stationIds = new Long[1];
                stationIds[0] = gkStation.getId();
                // 工位变量信息
                List<GkStationConfiguration> gkStationConfigurations = gkStationConfigurationMapper.selectInfoByStations(stationIds);
                int flag = 0;
                // 判断工位类型变量数量和工位变量数量是否一样，不一样则覆盖
                if (gkStationConfigurations.size()!=list.size()){
                    flag=1;
                }else {
                    int a = 1;
                    for (GkStationConfiguration gkStationConfiguration : gkStationConfigurations) {
                        for (GkStationTypeConfiguration stationTypeConfiguration : list) {
                            if (StringUtils.equals(gkStationConfiguration.getVariableName(), stationTypeConfiguration.getVariableName())) {
                                // 有一个一样的变量名称则加一计算数量
                                a+=1;
                                break;
                            }
                        }
                    }
                    if (a!=gkStationConfigurations.size()){
                        flag = 1;
                    }
                }
                if (flag==1) {
                    int a = 0;
                    for (GkStation station : gkStations) {
                        if (station.getSignalCommunicationId()!=null) {
                            if (station.getSignalCommunicationId().longValue() == gkStation.getSignalCommunicationId().longValue()) {
                                // 判断工位类型是否修改  1表示未修改
                                a = 1;
                            }
                        }
                    }
                    if (a==1) {
                        // 找到原有工位里面需要删除的工位变量
                        List<Long> deleteStationConfigurationIds = new ArrayList<>();
                        for (GkStationConfiguration gkStationConfiguration : gkStationConfigurations) {
                            int sign = 0;
                            for (GkStationTypeConfiguration stationTypeConfiguration : list) {
                                if (gkStationConfiguration.getVariableName().equals(stationTypeConfiguration.getVariableName())) {
                                    sign = 1;
                                    break;
                                }
                            }
                            if (sign == 0) {
                                deleteStationConfigurationIds.add(gkStationConfiguration.getId());
                            }
                        }
                        // 得到原有工位没有的变量数组
                        List<GkStationTypeConfiguration> addStationConfiguration = new ArrayList<>();
                        for (GkStationTypeConfiguration stationTypeConfiguration : list) {
                            int sign = 0;
                            for (GkStationConfiguration gkStationConfiguration : gkStationConfigurations) {
                                if (gkStationConfiguration.getVariableName().equals(stationTypeConfiguration.getVariableName())) {
                                    sign = 1;
                                }
                            }
                            if (sign == 0) {
                                addStationConfiguration.add(stationTypeConfiguration);
                            }
                        }
                        if (addStationConfiguration.size() > 0) {
                            list = addStationConfiguration;
                        } else {
                            list = new ArrayList<>();
                        }
                        if (deleteStationConfigurationIds!=null&&deleteStationConfigurationIds.size()>0){
                            gkStationConfigurationMapper.removeByIds(deleteStationConfigurationIds.toArray(new Long[0]));
                        }
                    }
                    // 修改工位类型先删除对应的原工位 模板和工位变量
                    List<GkStationConfigureTemplate> gkStationConfigureTemplates = gkStationConfigureTemplateMapper.selectAllInfo();
                    List<Long> templateIds = new ArrayList<>();
                    for (GkStationConfigureTemplate gkStationConfigureTemplate : gkStationConfigureTemplates) {
                        String[] split = gkStationConfigureTemplate.getStationIdList().split(",");
                        for (String s : split) {
                            if (!StringUtils.isEmpty(s)) {
                                long l = Long.parseLong(s);
                                if (l==gkStation.getId().longValue()){
                                    templateIds.add(gkStationConfigureTemplate.getId());
                                    break;
                                }
                            }
                        }
                    }
                    if (templateIds!=null&&templateIds.size()>0){
                        gkStationConfigureTemplateMapper.removeByIds((Long[]) templateIds.toArray(new Long[0]));
                    }
                    if (a==0) {
                        gkStationConfigurationMapper.removeByStationIds(stationIds);
                    }
                    if (list.size() > 0) {
                        List<GkStationConfiguration> gkStationConfigurationList = new ArrayList<>();
                        for (GkStationTypeConfiguration stationTypeConfiguration : list) {
                            if (stationTypeConfiguration.getType() != 3 && stationTypeConfiguration.getType() != 4) {
                                Date date = new Date();
                                GkStationConfiguration gkStationConfiguration = new GkStationConfiguration();
                                gkStationConfiguration.setStationId(gkStation.getId());
                                gkStationConfiguration.setType(stationTypeConfiguration.getType());
//                    gkStationConfiguration.setVariableAddress(stationTypeConfiguration.getVariableAddress() == null ? 0 : stationTypeConfiguration.getVariableAddress());
                                // namespace 在工位类型中没有所有不传
                                gkStationConfiguration.setVariableName(StringUtils.trim(stationTypeConfiguration.getVariableName()));
                                gkStationConfiguration.setDisplayName(StringUtils.trim(stationTypeConfiguration.getDisplayName()));
                                gkStationConfiguration.setDataType(StringUtils.trim(stationTypeConfiguration.getDataType()));
                                gkStationConfiguration.setVariableComments(StringUtils.trim(stationTypeConfiguration.getVariableComments()));
                                gkStationConfiguration.setVariableRemarks(StringUtils.trim(stationTypeConfiguration.getVariableRemarks()));
                                gkStationConfiguration.setDefaultValue(StringUtils.trim(stationTypeConfiguration.getDefaultValue()));
                                gkStationConfiguration.setVariableIndex(stationTypeConfiguration.getVariableIndex());
                                gkStationConfiguration.setResultConversion(stationTypeConfiguration.getResultConversion());
                                gkStationConfiguration.setZeroValue(stationTypeConfiguration.getZeroValue()==null?"":stationTypeConfiguration.getZeroValue());
                                gkStationConfiguration.setOneValue(stationTypeConfiguration.getOneValue()==null?"":stationTypeConfiguration.getOneValue());
                                gkStationConfiguration.setThreeValue(stationTypeConfiguration.getThreeValue()==null?"":stationTypeConfiguration.getThreeValue());
                                gkStationConfiguration.setFourValue(stationTypeConfiguration.getFourValue()==null?"":stationTypeConfiguration.getFourValue());
                                gkStationConfiguration.setTwoValue(stationTypeConfiguration.getTwoValue()==null?"":stationTypeConfiguration.getTwoValue());
                                gkStationConfiguration.setFiveValue(stationTypeConfiguration.getFiveValue()==null?"":stationTypeConfiguration.getFiveValue());
                                gkStationConfiguration.setCheckLength(stationTypeConfiguration.getCheckLength() == null ? 0 : stationTypeConfiguration.getCheckLength());
                                gkStationConfiguration.setCreateAt(date);
                                gkStationConfiguration.setLastModifyAt(date);
                                gkStationConfiguration.setToUse(1);
                                gkStationConfigurationList.add(gkStationConfiguration);
                            }
                        }
                        gkStationConfigurationMapper.saveList(gkStationConfigurationList);
                    }
                }
            }
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @Transactional
    @Override
    public AjaxResult removeByIds(Long[] ids) {
        int row = gkStationMapper.removeByIds(ids);
        if (row>0){
            List<GkStationConfigurationVo> gkStationConfigurationVos = gkStationConfigurationMapper.selectInfoByType2StationIds(Arrays.asList(ids));
            List<Long> stationConfigurationIds = gkStationConfigurationVos.stream().map(GkStationConfigurationVo::getId).collect(Collectors.toList());
            gkStationConfigurationMapper.removeByStationIds(ids);
            if (stationConfigurationIds!=null&&stationConfigurationIds.size()>0){
                gkStationConfigurationValuesMapper.deleteByStationConfigurationIds(stationConfigurationIds);
            }
            if (row>0) {
                gkStationEventMapper.removeByStationIds(ids);
                return AjaxResult.success();
            }
        }
        return AjaxResult.error();
    }

    @Override
    public AjaxResult oneClickConfiguration(Long[] ids) {
        Map<String,Object> map1 = new HashMap<>();
        log.info("访问一键配置接口");
        List<GkStationConfiguration> gkStationConfigurations = new ArrayList<>();
        List<NodeDTOV2> nodeDTOV2List = new ArrayList<>();
        OpcUaWriteReqV2 opcUaWriteReqV2 = new OpcUaWriteReqV2();

        if (ids!=null&&ids.length>0) {
            List<GkStation> gkStations = gkStationMapper.selectNoConfigurationByIds(ids);
            if (gkStations==null||gkStations.size()==0){
                return AjaxResult.success("工位已配置");
            }
            List<Long> collect1 = gkStations.stream().map(GkStation::getId).collect(Collectors.toList());
            List<GkStationConfiguration> gkStationConfigurationList = gkStationConfigurationMapper.selectInfoByType1Stations(collect1);
            List<Long> collect = gkStations.stream().map(GkStation::getSignalCommunicationId).distinct().collect(Collectors.toList());
            if (collect!=null&&collect.size()>0){
                List<GkSignalCommunication> gkSignalCommunications = gkSignalCommunicationMapper.selectInfoByIds(collect);
                if (gkSignalCommunications!=null&&gkSignalCommunications.size()==1){
                    for (GkSignalCommunication gkSignalCommunication : gkSignalCommunications) {
                        if (gkSignalCommunication.getCommunicationProtocol()!=null){
                            opcUaWriteReqV2.setUid(gkSignalCommunication.getCommunicationProtocol());
                        }
                    }
                }
            }
//            if (StringUtils.isEmpty(opcUaWriteReqV2.getUid())){
//                return AjaxResult.error("连接异常");
//            }
            List<Long> productLineIds = gkStations.stream().map(GkStation::getProductionLineId).distinct().collect(Collectors.toList());
            List<GkProductionLineVo> gkProductionLineVos = gkProductionLineMapper.selectInfoByIds(productLineIds);
            String productName = "";
            OpcUaList opcUaList = ReadOpcUaNodeInfoTool.GetOpcUaList();
            List<OpcUa> uaList = opcUaList.getOpcUaList();
            List<Node> fileNodeList = new ArrayList<>();
            for (OpcUa opcUa : uaList) {
                if (opcUa.getUid().equals(opcUaWriteReqV2.getUid())){
                    fileNodeList = opcUa.getNodeList();
                }
            }
            for (GkStationConfiguration gkStationConfiguration : gkStationConfigurationList) {
                if (gkStationConfiguration.getVariableName().equals("ProductType")){
                    productName = gkStationConfiguration.getDefaultValue();
                }
                if (gkStationConfiguration.getDataType().equals("boolean")){
                    gkStationConfiguration.setDataType("bool");
                }
                gkStationConfiguration.setDataType(gkStationConfiguration.getDataType().toUpperCase());
                NodeDTOV2 nodeDTOV2 = new NodeDTOV2();
                Object obj = new Object();
                if (gkStationConfiguration.getDataType().equals("BOOL")){
                    if (StringUtils.equals(gkStationConfiguration.getDefaultValue(),"true")) {
                        obj = Boolean.TRUE;
                    }else {
                        obj = Boolean.FALSE;
                    }
                }else if (gkStationConfiguration.getDataType().equals("STRING")){
                    if (com.sgl.common.utils.StringUtils.isEmpty(gkStationConfiguration.getDefaultValue())) {
                        obj = null;
                    }else {
                        obj = gkStationConfiguration.getDefaultValue();
                    }
                }else if (StringUtils.isEmpty(gkStationConfiguration.getDefaultValue())){
                    obj = null;
                }else {
                    Pattern pattern = Pattern.compile("^[-+]?[0-9]+(\\.[0-9]+)?$");
                    Matcher isNum = pattern.matcher(gkStationConfiguration.getDefaultValue());
                    if (!isNum.matches()){
                        return AjaxResult.error(gkStationConfiguration.getDisplayName()+"输入值类型不匹配");
                    }
                    if (gkStationConfiguration.getDefaultValue().indexOf('.')>0){
                        obj = Float.parseFloat(gkStationConfiguration.getDefaultValue());
                    }else {
                        obj = Integer.parseInt(gkStationConfiguration.getDefaultValue());
                    }
                }

                nodeDTOV2.setNodeType(gkStationConfiguration.getDataType());
                String nodeName = new String();
                for (GkStation gkStation : gkStations) {
                    if (gkStation.getId()==gkStationConfiguration.getStationId()) {
                        if (gkStationConfiguration.getType()==1) {
                            nodeName = "DB_RECIPE."+((gkStation.getCode()==null||gkStation.getCode().equals(""))?"":(gkStation.getCode()+"."))+gkStationConfiguration.getVariableName();
                        }
                        if (gkStationConfiguration.getType()==2) {
                            for (GkProductionLineVo gkProductionLineVo : gkProductionLineVos) {
                                if (gkProductionLineVo.getId().longValue()==gkStation.getProductionLineId().longValue()) {
                                    nodeName = gkProductionLineVo.getCode()+"."+((gkStation.getCode()==null||gkStation.getCode().equals(""))?"":(gkStation.getCode()+"."))+gkStationConfiguration.getVariableName();
                                }
                            }
                        }
                        if (gkStationConfiguration.getType()==3) {
                            // 写入交互变量类型  3写
                            nodeName = "data_pc_plc.pc_reply."+gkStationConfiguration.getVariableName();
                        }
                        if (gkStationConfiguration.getType()==4){
                            // 读取交互变量类型  4读
                            nodeName = "data_pc_plc.plc_request."+gkStationConfiguration.getVariableName();
                        }
                    }
                }
                map1.put(nodeName,obj);
                nodeDTOV2.setNodeName(nodeName);
                if (CollUtil.isNotEmpty(fileNodeList)){
                    for (Node node : fileNodeList) {
                        if (node.getDisplayName().equals(nodeName)) {
                            nodeDTOV2.setNodeId(node.getNodeId());
                        }
                    }
                }
                nodeDTOV2.setNodeValue(obj);
                log.info("设置参数：{}",nodeDTOV2.toString());
                // 设置的工位变量
                nodeDTOV2List.add(nodeDTOV2);
            }
            opcUaWriteReqV2.setWriteNodeList(nodeDTOV2List);

            try {
                String s = null;
                Ret<List<NodeDTOV2>> listRet = null;
                if (communication.equals("socket")) {
                    BufferedWriter bufferedWriter = ScheduledTask.bufferedWriter;
                    BufferedReader bufferedReader = ScheduledTask.bufferedReader;
                    SocketDataVo socketDataVo = new SocketDataVo();
                    socketDataVo.setUid(opcUaWriteReqV2.getUid());
                    List<ServiceData> nodeList = new ArrayList<>();
                    for (NodeDTOV2 nodeDTOV2 : nodeDTOV2List) {
                        ServiceData serviceData = new ServiceData();
                        serviceData.setNodeName(nodeDTOV2.getNodeName());
                        serviceData.setDisplayName(nodeDTOV2.getNodeName());
                        serviceData.setNodeValue(nodeDTOV2.getNodeValue());
                        serviceData.setNodeType(nodeDTOV2.getNodeType());
                        nodeList.add(serviceData);
                    }
                    socketDataVo.setNodeList(nodeList);
                    bufferedWriter.write("setData?" + JSON.toJSONString(socketDataVo) + "\n");
                    bufferedWriter.flush();
                    s = bufferedReader.readLine();
                }else if (communication.equals("plc")) {
                    if (!OpcUATool.isConnect(opcUaServiceV2, opcUaWriteReqV2)) {
                        int i = 0;
                        for (i=0 ; i < 10; i++) {
                            if (OpcUATool.isConnect(opcUaServiceV2,opcUaWriteReqV2)){
                                break;
                            }
                            Thread.sleep(200);
                        }
                        if (i==10) {
                            return AjaxResult.error("plc连接异常，请重新下发参数");
                        }
                    }
                    opcUaWriteReqV2 = OpcUATool.valueIsChange(opcUaServiceV2,opcUaWriteReqV2);
                    for (int i = 0; i < 10; i++) {
                        listRet = opcUaServiceV2.writeData(opcUaWriteReqV2);
                        if (listRet!=null){
                            break;
                        }
                    }
                }
                // todo 一键下发保存参数下发记录
                Map<Long, List<GkStation>> listMap = gkStations.parallelStream().collect(Collectors.groupingBy(GkStation::getProductionLineId));
                GkSettingLog gkSettingLog = new GkSettingLog();
                String setStation = new String();
                for (GkProductionLineVo gkProductionLineVo : gkProductionLineVos) {
                    List<GkStation> gkStations2 = listMap.get(gkProductionLineVo.getId());
                    if (CollUtil.isNotEmpty(gkStations2)) {
                        List<String> stationNames = gkStations2.stream().filter(gk -> StringUtils.isNotEmpty(gk.getName())).map(GkStation::getName).collect(Collectors.toList());
                        String join = StringUtils.join(stationNames, ",");
                        setStation += gkProductionLineVo.getName()+":"+"("+join+");";
                    }
                }
                gkSettingLog.setProductName(productName);
                gkSettingLog.setSetStation(setStation);
                gkSettingLogService.add(gkSettingLog);
//                if (StringUtils.isNotEmpty(productName)) {
//                    List<GkReservedInfo> gkReservedInfoList = new ArrayList<>();
//                    GkReservedInfo gkReservedInfo = new GkReservedInfo();
//                    gkReservedInfo.setId(1l);
//                    gkReservedInfo.setValue(productName);
//                    gkReservedInfoList.add(gkReservedInfo);
//                    GkProduct gkProduct = new GkProduct();
//                    gkProduct.setTemplateName(productName);
//                    List<GkProduct> gkProducts = gkProductMapper.list(gkProduct);
//                    GkReservedInfo gkReservedInfo1 = new GkReservedInfo();
//                    if (CollUtil.isNotEmpty(gkProducts)){
//                        for (GkProduct product : gkProducts) {
//                            gkReservedInfo1.setValue(product.getCode());
//                            gkReservedInfo1.setId(2l);
//                        }
//                    }
//                    gkReservedInfoList.add(gkReservedInfo1);
//                    int row = gkReservedInfoMapper.editList(gkReservedInfoList);
//                }
                if (listRet==null&&s==null){
                    return AjaxResult.error("下发参数失败，请重新下发参数");
                }


                List<NodeDTOV2> data = new ArrayList<>();
                if (communication.equals("socket")) {
                    SocketDataVo socketDataVo1 = JSON.parseObject(s, SocketDataVo.class);
                    List<ServiceData> nodeList1 = socketDataVo1.getNodeList();
                    for (ServiceData serviceData : nodeList1) {
                        NodeDTOV2 nodeDTOV2 = new NodeDTOV2();
                        nodeDTOV2.setNodeValue(serviceData.getNodeValue());
                        nodeDTOV2.setNodeType(serviceData.getNodeType());
                        nodeDTOV2.setNodeName(serviceData.getNodeName());
                        nodeDTOV2.setNodeId(serviceData.getNodeId());
                        nodeDTOV2.setDisplayName(serviceData.getDisplayName());
                        nodeDTOV2.setStatusCode(0l);
                        data.add(nodeDTOV2);
                    }
                }else if (communication.equals("plc")){
                    data = listRet.getData();
                }

                for (NodeDTOV2 datum : data) {
                    if (datum.getStatusCode()>0) {
                        for (GkStationConfiguration gkStationConfiguration : gkStationConfigurationList) {
                            String nodeName = new String();
                            for (GkStation gkStation : gkStations) {
                                if (gkStation.getId().longValue()==gkStationConfiguration.getStationId().longValue()){
                                    if (gkStationConfiguration.getType()==1) {
                                        nodeName = "DB_RECIPE."+((gkStation.getCode()==null||gkStation.getCode().equals(""))?"":(gkStation.getCode()+"."))+gkStationConfiguration.getVariableName();
                                    }
                                    if (gkStationConfiguration.getType()==2) {
                                        for (GkProductionLineVo gkProductionLineVo : gkProductionLineVos) {
                                            if (gkProductionLineVo.getId().longValue()==gkStation.getProductionLineId().longValue()){
                                                nodeName = gkProductionLineVo.getCode()+"."+((gkStation.getCode()==null||gkStation.getCode().equals(""))?"":(gkStation.getCode()+"."))+gkStationConfiguration.getVariableName();
                                            }
                                        }
                                    }
                                    if (gkStationConfiguration.getType()==3) {
                                        // 写入交互变量类型  3写
                                        nodeName = "data_pc_plc.pc_reply."+gkStationConfiguration.getVariableName();
                                    }
                                    if (gkStationConfiguration.getType()==4){
                                        // 读取交互变量类型  4读
                                        nodeName = "data_pc_plc.plc_request."+gkStationConfiguration.getVariableName();
                                    }
                                }
                            }
                            if (datum.getDisplayName().equals(nodeName)) {
                                gkStationConfiguration.setStatusMsg(datum.getStatusMsg());
                                gkStationConfigurations.add(gkStationConfiguration);
                            }
                        }
                    }
                    log.info("多工位设置返回信息：{}",datum.toString());
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
            gkStationMapper.editTypeByStationIds(Arrays.asList(ids),StationDict.CONFIGURED.value);
            if (gkStationConfigurations!=null&&gkStationConfigurations.size()>0) {
                Map<Long, List<GkStationConfiguration>> map = gkStationConfigurations.parallelStream().collect(Collectors.groupingBy(GkStationConfiguration::getStationId));
                // 出现未设置成功变量 把他们工位状态改为 部分设置成功
                List<Long> noConfigureStationId = new ArrayList<>();
                Iterator<Long> set = map.keySet().iterator();
                while (set.hasNext()){
                    noConfigureStationId.add(set.next());
                }
                gkStationMapper.editTypeByStationIds(noConfigureStationId,StationDict.PARTIALSETTINGS.value);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return AjaxResult.success("部分配置成功",map);
            }
        }else {
            return AjaxResult.success("暂时没有未配置工位");
        }
        List<Long> list = Arrays.asList(ids);
        // todo 做一键设置操作延时定位todo
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return AjaxResult.success("设置成功，设置的工位id为："+list.toString());
    }

    @Override
    public int countAll() {
        return gkStationMapper.countAll();
    }


}
